package com.ruoyi.contract.controller;

import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.contract.domain.ContractAppendices;
import com.ruoyi.contract.domain.InvoiceAttachment;
import com.ruoyi.contract.domain.contractVo.ContractAllRelevantVo;
import com.ruoyi.contract.domain.invoiceVo.InvoiceExport;
import com.ruoyi.contract.domain.invoiceVo.SelectInvoiceVo;
import com.ruoyi.contract.tools.FileUtil;
import com.ruoyi.framework.config.ServerConfig;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.contract.domain.Invoice;
import com.ruoyi.contract.service.IInvoiceService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;

/**
 * 发票Controller
 * 
 * @author ruoyi
 * @date 2024-10-18
 */
@RestController
@RequestMapping("/contract/Invoice")
public class InvoiceController extends BaseController
{
    @Autowired
    private IInvoiceService invoiceService;

    @Autowired
    private ServerConfig serverConfig;

    /**
     * 查询发票列表
     */
    @PreAuthorize("@ss.hasPermi('contract:Invoice:list')")
    @GetMapping("/list")
    public TableDataInfo list(Invoice invoice)
    {
        startPage();
        List<SelectInvoiceVo> list = invoiceService.selectInvoiceList(invoice);
        return getDataTable(list);
    }

    /**
     * 导出发票列表
     */
    @PreAuthorize("@ss.hasPermi('contract:Invoice:export')")
    @Log(title = "发票", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, @RequestParam Long[] invoiceIds)
    {
        List<InvoiceExport> list = invoiceService.selectInvoiceByInvoiceIds(invoiceIds);
        ExcelUtil<InvoiceExport> util = new ExcelUtil<InvoiceExport>(InvoiceExport.class);
        util.exportExcel(response, list, "发票台账信息");
    }

    /**
     * 获取发票详细信息
     */
    @PreAuthorize("@ss.hasPermi('contract:Invoice:query')")
    @GetMapping(value = "/{invoiceId}")
    public AjaxResult getInfo(@PathVariable("invoiceId") Long invoiceId)
    {
        return success(invoiceService.selectInvoiceByInvoiceId(invoiceId));
    }

    /**
     * 新增发票
     */
    @PreAuthorize("@ss.hasPermi('contract:Invoice:add')")
    @Log(title = "发票", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Invoice invoice)
    {
        return invoiceService.insertInvoice(invoice);
    }

    /**
     * 发票文件上传(单个)
     */
//    @Log(title = "发票上传", businessType = BusinessType.INSERT)
//    @PostMapping("/upload")
//    public AjaxResult upload(MultipartFile file) {
//        if (file == null || file.isEmpty()) {
//            // 如果文件为空，返回错误信息
//            return AjaxResult.error("上传的文件不能为空");
//        }
//        try {
//            // 上传文件路径
//            String filePath = RuoYiConfig.getUploadPath();
//            // 上传并返回新文件名称
//            String fileName = FileUploadUtils.upload(filePath, file);
//            String url = serverConfig.getUrl() + fileName;
//            AjaxResult ajax = AjaxResult.success();
//            ajax.put("url", url);
//            ajax.put("fileName", fileName);
//            ajax.put("newFileName", FileUtils.getName(fileName));
//            ajax.put("originalFilename", file.getOriginalFilename());
//            return ajax;
//        } catch (Exception e) {
//            // 返回错误信息
//            return AjaxResult.error("文件上传失败：" + e.getMessage());
//        }
//    }

    /**
     * 批量下载发票文件
     */
    @Log(title = "发票台账", businessType = BusinessType.EXPORT)
    @PostMapping("/download")
    public void downloadContractFiles(HttpServletResponse response, @RequestBody Long[] invoiceIds) throws IOException {
        // 创建临时文件夹
        String tempDirPath = System.getProperty("java.io.tmpdir") + File.separator + "invoices";
        File tempDir = new File(tempDirPath);
        if (!tempDir.exists()) {
            tempDir.mkdirs();
        }
        List<SelectInvoiceVo> selectInvoiceVos = new ArrayList<>();
        for (Long invoiceId : invoiceIds) {
            // 查询发票信息
            SelectInvoiceVo invoice = invoiceService.selectInvoiceByInvoiceId(invoiceId);
            // 检查发票信息是否存在
            if (invoice != null) {
                selectInvoiceVos.add(invoice);
            }
        }

        String zipFolderPath = tempDirPath + File.separator + "发票";
        // 创建父文件夹:发票
        FileUtil.createFolder(zipFolderPath);
        for (SelectInvoiceVo selectInvoiceVo : selectInvoiceVos) {
            // 根据发票所属公司名创建子文件夹
            String companyName = selectInvoiceVo.getBelongingCompanyName();
            String subFolderPath = zipFolderPath + File.separator + companyName;
            FileUtil.createFolder(subFolderPath);

            // 添加发票文件到子文件夹中
            String pdfAddress = selectInvoiceVo.getPdfAddress().replaceFirst("^/profile", "");
            File sourceFile = new File(RuoYiConfig.getProfile() + pdfAddress);
            if (sourceFile.exists()) {
                FileUtil.copyFileToFolder(sourceFile, subFolderPath);
            } else {
                System.out.println("发票文件不存在: " + sourceFile.getPath());
            }
            // 添加发票附件文件到子文件夹中
            for (InvoiceAttachment invoiceAttachment : selectInvoiceVo.getInvoiceAttachmentInfo()) {
                if (invoiceAttachment.getPdfAddress() != null) {
                    String attachmentAddress = invoiceAttachment.getPdfAddress().replaceFirst("^/profile", "");
                    File appendixFile = new File(RuoYiConfig.getProfile() + attachmentAddress);
                    if (appendixFile.exists()) {
                        FileUtil.copyFileToFolder(appendixFile, subFolderPath);
                    } else {
                        System.out.println("附件文件不存在: " + appendixFile.getPath());
                    }
                }
            }
        }
        // 压缩发票文件夹
        String zipFilePath = tempDirPath + File.separator + "发票.zip";
        FileUtil.zipFolder(Paths.get(zipFolderPath), zipFilePath);
        // URL 编码文件名
        String encodedFileName = URLEncoder.encode("发票.zip", StandardCharsets.UTF_8.toString());
        // 返回压缩文件给前端
        response.setContentType("application/zip");
        response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedFileName + "\"");

        try (InputStream is = new FileInputStream(zipFilePath);
             OutputStream os = response.getOutputStream()) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = is.read(buffer)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
        } catch (IOException e) {
            // 处理 IOException
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "文件下载失败");
        } finally {
            // 删除临时文件夹及其内容
            FileUtil.deleteDirectory(Paths.get(tempDirPath));
        }
    }



    /**
     * 修改发票
     */
    @PreAuthorize("@ss.hasPermi('contract:Invoice:edit')")
    @Log(title = "发票", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Invoice invoice)
    {
        return invoiceService.updateInvoice(invoice);
    }

    /**
     * 删除发票
     */
    @PreAuthorize("@ss.hasPermi('contract:Invoice:remove')")
    @Log(title = "发票", businessType = BusinessType.DELETE)
	@DeleteMapping("/{invoiceIds}")
    public AjaxResult remove(@PathVariable Long[] invoiceIds)
    {
        return invoiceService.deleteInvoiceByInvoiceIds(invoiceIds);
    }
}